﻿/* 字典管理 */
var dictManager = (function (prefix) {
    var manager = cacheManager.create(prefix);

    //回溯树tree，寻找指定id的节点,若给定path，则path保存了路径
    manager.findTreeNode = function (id, tree, path) {
        var i, val;
        for (i = tree.length - 1; i >= 0; i--) {
            if (path) {
                path.push(tree[i]);
            }
            if (tree[i].attr.id === id) {
                return tree[i];
            }
            if (tree[i].children) {
                val = arguments.callee(id, tree[i].children, path);
                if (val) {
                    return val;
                }
            }
            if (path) {
                path.pop();
            }
        }
    };

    manager.getDict = function (code) {
        var cache = this.get(code);
        if (cache) {
            return $.Deferred().resolve(cache);
        }
        var self = this;
        //获取某一字典集合下所有字典项，包括字典项子项
        return $.postJson("/JsTree/GetDictTree", {
            code: code
        }).done(function (data) {
            self.set(code, data);
        });
    };

    manager.getDictVal = function (code, value) {
        if (value) {
            //临时缓存(匿名对象)，刷新页面就销毁！
            var
                _prefix = this.genKey(code + "_temp"),
                _manager = cacheManager.create(_prefix, {});
            var
                key = value,
                val = _manager.get(key);
            if (val) {
                return $.Deferred().resolve(val);
            }
            var self = this;
            return this
                .getDict(code)
                .then(function (data) {
                    var v = self.findTreeNode(value, data);
                    _manager.set(key, v);
                    return v;
                });
        }
        return $.Deferred().resolve();
    };

    return manager;
})("DICT_");

// ktDict 字典选择控件
function KtDict(option, val) {
    if ($.type(option) === 'undefined') {
        return;
    }
    var ins;
    if ($.type(option) === 'string') {
        ins = this.data('ktDict');
        return ins[option](val);
    }
    option.code = option.code || this.attr('kt-dict-code');   //字典代码
    option.value = option.value || this.attr('kt-dict-value');//字典值
    option.root = option.root || this.attr('kt-dict-root');   //查找根节点
    option.input = option.input;                              //点击对象
    option.valueinput = option.valueinput || null;            //值对象

    ins = new KtDict();
    ins.option = option;
    ins.code = option.code;
    ins.value = option.value;
    ins.root = option.root;
    ins.input = option.input;
    ins.valueinput = option.valueinput;
    ins.enableSearch = false;
    ins.valueAttrs = {};
    ins.ele = this;
    ins.provider = null;
    ins.init();
    this.data('ktDict', ins);
    return this;
}
KtDict.Providers = {
    caches: [
        {
            match: /^goodscategory$/i,
            data: function (code, value) {
                var self = this;
                var tempValue = value;
                return {
                    "animation": 0,
                    "check_callback": true,
                    "data": function (node, callback) {
                        var _this = this;
                        var isRoot = (node.id == "#");
                        var root = (isRoot ? "00000000-0000-0000-0000-000000000000" : node.id);
                        var select = tempValue;
                        tempValue = null;
                        $
                            .postJson("/JsTree/GetGoodsCategoryTree", { root: root, selectId: select, withRoot: isRoot })
                            .done(function (data) {
                                callback.call(_this, data);
                            });
                    }
                };
            },
            selectedNode: function (node) {
                return { code: "goodscategory", value: node.id };
            },
            setValue: function (value, code) {
                var ele = this.ele,
                    input = this.option.input;
                if (!value) {
                    ele.text('');
                    if (input) {
                        $(input).val('');
                    }
                } else {
                    $
                        .postJson("/JsTree/GetGoodsCategoryInfo", { Id: value })
                        .done(function (data) {
                            if (!data) {
                                ele.text('');
                                if (input) {
                                    $(input).val('');
                                }
                                console.warn('dictionary not found! code ="' + code + '", value="' + value + '"');
                            } else {
                                ele.text(data.Name);
                                if (input) {
                                    $(input).val(data.Name);
                                }
                            }
                        });
                }
            }
        },
        {
            match: /^servicecategory$/i,
            data: function (code, value) {
                var self = this;
                var tempValue = value;
                return {
                    "animation": 0,
                    "check_callback": true,
                    "data": function (node, callback) {
                        var _this = this;
                        var isRoot = (node.id == "#");
                        var root = (isRoot ? "00000000-0000-0000-0000-000000000000" : node.id);
                        var select = tempValue;
                        tempValue = null;
                        $
                            .postJson("/JsTree/GetServiceCategoryTree", { root: root, selectId: select, withRoot: isRoot })
                            .done(function (data) {
                                callback.call(_this, data);
                            });
                    }
                };
            },
            selectedNode: function (node) {
                return { code: "servicecategory", value: node.id };
            },
            setValue: function (value, code) {
                var ele = this.ele,
                    input = this.option.input;
                if (!value) {
                    ele.text('');
                    if (input) {
                        $(input).val('');
                    }
                } else {
                    $
                        .postJson("/JsTree/GetServiceCategoryInfo", { catId: value })
                        .done(function (data) {
                            if (!data) {
                                ele.text('');
                                if (input) {
                                    $(input).val('');
                                }
                                console.warn('dictionary not found! code ="' + code + '", value="' + value + '"');
                            } else {
                                ele.text(data.Name);
                                if (input) {
                                    $(input).val(data.Name);
                                }
                            }
                        });
                }
            }
        },
        {
            match: /.*/,
            core_data: function (code, value) {
                var self = this;
                return {
                    progressive_render: true,
                    data: function (node, success) {
                        dictManager
                            .getDict(code)
                            .done(function (data) {
                                var path = [];
                                if (self.root) {
                                    data = dictManager.findTreeNode(self.root, data);
                                }
                                dictManager.findTreeNode(value, data, path);
                                $('#dict-tree').data("dict-path", path);
                                success(data);
                            });
                    }
                };
            },
            selectedNode: function (node) {
                return { code: "", value: node.id };
            },
            setValue: function (val, type) {
                var ele = this.ele,
                    input = this.option.input,
                    value = this.value;
                if (!val) {
                    ele.text('');
                    if (input) {
                        $(input).val('');
                    }
                } else {
                    this.getDictVal(type, val).done(function (data) {
                        if (!data) {
                            ele.text('');
                            if (input) {
                                $(input).val('');
                            }
                            console.warn('dictionary not found! code ="' + type + '", value="' + val + '"');
                        } else {
                            ele.text(data.data.title);
                            if (input) {
                                $(input).val(data.data.title);
                            }
                        }
                    });
                }
            }
        }
    ],
    getProvider: function (code) {
        var provider;
        for (var i = 0, j = this.caches.length; i < j; i++) {
            provider = this.caches[i];
            if (provider.match.test(code)) { break; }
        }
        return provider;
    }
};
KtDict.prototype = {
    setValue: function (value, code, triggerEvent) {
        var provider = this.provider;
        provider.setValue.apply(this, arguments);
        if (value !== this.value) {
            //仅当实际的修改发生时（从界面选取等）时，才触发change事件。初始化值时不应该触发事件。
            if (triggerEvent) {
                this.ele.trigger('change.ktDict', value);
            }
            $("#category-dialog #txtGcName").blur();//fix焦点状态导致无法再次触发下拉
            this.value = value;
        }
        if (this.option.valueinput) { $(this.option.valueinput).val(value); }
    },

    bindDictTree: function (code, value, callback) {
        var self = this;
        $('#dict-selector').data('ktDict', self);

        var provider = this.provider;
        var data = provider.data.apply(this, arguments);

        var $tree = $("#dict-tree");
        var $jstree = $tree.data("jstree");
        $tree
        .off("select_node.jstree").on("select_node.jstree", function (event, data) {
            var node = data.node;
            var nodeval = provider.selectedNode(node);
            self.setValue(nodeval.value, nodeval.code, true);
            self.hideSelector();
        });
        if (!$jstree) {
            $tree
                .jstree({
                    plugins: [],
                    //core: {
                    //    "animation": 0,
                    //    "check_callback": true,
                    //    data: function (node, call) { }
                    //}
                    core: data
                });
        }
        else {
            $.extend(true, $jstree.settings.core, data);
            //$tree.jstree("refresh", false, true);
            $jstree.refresh(false, true);
        }
        if (callback) {
            callback();
        }
    },

    hideSelector: function () {
        $("#dict-selector").hide();
        var before = KtDict.showing;
        KtDict.showing = false;
        return before;
    },

    showSelector: function () {
        if (KtDict.showing === true) {
            return;
        }
        $("#dict-selector").show();
        var self = $("#dict-selector").data('ktDict');
        if (this.input && this.enableSearch) {
            $(this.input).keydown(function (event) {
                if (self.keywordTimer) {
                    clearTimeout(self.keywordTimer);
                }
                self.keywordTimer = setTimeout(function () {
                    self.keyword = $(self.input).val().replace(/\s/g, '');
                    self.keywordSearch();
                }, 500);
            });
        };
        KtDict.showing = true;
    },

    keywordSearch: function () {
        var keyword = this.keyword;
        if (keyword && keyword.length > 2) {
            $('#dict-tree').jstree('refresh');
            delete this['keyword'];
        }
    },

    init: function () {
        var
            code = this.code,
            value = this.value;

        this.provider = KtDict.Providers.getProvider(code);

        this.setValue(value, code);

        if (this.option.input) {
            var self = this;
            //字典选择的DIV
            if ($("#dict-selector").length === 0) {
                $(document.body).append('<div id="dict-selector" style=" width:200px;z-index:99999;padding:3px;position:absolute;display:none;">' + '<div id="dict-tree" class="e-bg-fff" style="border:solid 1px #ccc;height: 300px;overflow:auto;position:absolute;top:0px;left:0px;"></div>' + '</div>');
            }
            $(this.option.input).off(".ktdict")
                .on('focus.ktdict', function (e) {
                    if (KtDict.showing === true && $("#dict-selector").data('ktDict') === self) {
                        return;
                    }
                    var ktDict = self,
                        ele = $(this);
                    var code = ktDict.code,
                        value = ktDict.value;

                    ktDict.bindDictTree(code, value, function () {
                        var offset = ele.offset();
                        self.showSelector();
                        var pop = $("#dict-selector");
                        var poph = pop.outerHeight();
                        var inputH = ele.outerHeight();
                        if (document.body.offsetHeight < (offset.top + inputH + poph)) {
                            offset.top -= poph;
                        } else {
                            offset.top += inputH;
                        }
                        pop.css(offset);
                    });

                    $(this).select();
                })
                .on('blur.ktdict', function (e) {
                    var ele = $(this);
                    if (ele.val() === '') {
                        self.setValue('', '', true);
                    }
                })
                .on('click.ktdict', function (e) {
                    e.stopPropagation();
                })
                .on("keydown.ktdict", function (e) {
                    if (e.keyCode === 9 || e.keyCode === 27) {
                        self.hideSelector();
                    }
                });
        }
    }
};

$.fn.ktDict = KtDict;
$(document).on('click.ktdict', function (e) {
    if (KtDict.showing && !$(e.target).is('#dict-selector, #dict-selector *')) {
        $('#dict-selector').data('ktDict').hideSelector();
    }
});